<template>
  <div class="resizeWrapper" ref="resizeWrapper" :style="{ flexDirection: props.flex }">
    <div class="leftWrapper" :style="{ width: leftWidthWrapepr, height: topHeightWrapepr }">
      <slot name="left"></slot>
      <slot name="top" :style="{ width: rightWidthWrapepr, height: bottomHeightWrapepr }"></slot>
    </div>
    <div
      class="drapLine"
      :class="{
        drapLine: true,
        EwResize: props.flex === 'row',
        NResize: props.flex === 'column',
        row: props.flex === 'row',
        column: props.flex === 'column'
      }"
      ref="drapLine"
      @mousedown="dragStart"
      :style="{ width: driverWidthWrapepr, height: driverHeightWrapepr }"
    ></div>
    <div
      class="rightWrapper"
      :class="{ auto: rightWidthWrapepr !== 0 || props.flex !== 'column' }"
      :style="{ width: rightWidthWrapepr }"
    >
      <slot name="right"></slot>
      <slot name="bottom"></slot>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue'
const isDrag = ref<Boolean>(false)
const resizeWrapper = ref<HTMLElement | null>(null)
const drapLine = ref<HTMLElement | null>(null)
const leftWidth = ref<Number>(350) // 左侧宽度
const rightWidth = ref<Number>(0) // 右侧宽度
const topHeight = ref<Number>(550) // 上方高度
const bottomHeight = ref<Number>(0) // 下方高度
const props = defineProps({
  leftWidthLimit: {
    type: Object,
    default: () => ({ min: 350, max: 900 })
  },
  topHeightLimit: {
    type: Object,
    default: () => ({ min: 300, max: 600 })
  },
  driver: {
    type: Number,
    default: 1
  },
  flex: {
    type: Text,
    default: 'row'
  }
})
const driverWidthWrapepr = computed(() => (props.flex === 'column' ? '100%' : `${props.driver}px`))
const driverHeightWrapepr = computed(() => (props.flex === 'row' ? '100%' : `${props.driver}px`))
const leftWidthWrapepr = computed(() => (props.flex === 'column' ? '100%' : `${leftWidth.value}px`))
const rightWidthWrapepr = computed(() =>
  props.flex === 'column' ? '100%' : rightWidth.value === 0 ? 'auto' : `${rightWidth.value}px`
)
const topHeightWrapepr = computed(() =>
  props.flex === 'row' ? '100% !important' : `${topHeight.value}px`
)
const bottomHeightWrapepr = computed(() =>
  rightWidth.value === 0 ? 'auto' : `${bottomHeight.value}px`
)
const dragStart = (e: MouseEvent) => {
  e.preventDefault()
  isDrag.value = true
  document.addEventListener('mousemove', onDragMove) //鼠标移动事件
  document.addEventListener('mouseup', onDragEnd) // 鼠标释放事件
}
// 鼠标移动事件
const onDragMove = (e: MouseEvent) => {
  e.preventDefault()
  // 如果不是拖曳状态或者容器还没有准备好
  if (!isDrag.value || !resizeWrapper.value) return
  // 获取外侧容器的大小
  const resizeWrapperRect = resizeWrapper.value.getBoundingClientRect()
  const drapLineRect = drapLine.value.getBoundingClientRect()
  if (props.flex === 'row') {
    // 计算拖曳的坐标以及左右两边的宽度
    const newWidth = e.clientX - resizeWrapperRect.left
    // 左侧最小宽度
    if (newWidth <= props.leftWidthLimit.min) return
    if (newWidth >= props.leftWidthLimit.max) return
    // 设置两侧容器的宽度
    leftWidth.value = newWidth
    rightWidth.value = resizeWrapperRect.width - leftWidth.value - drapLineRect.width
  } else {
    // 计算拖曳的坐标以及左右两边的宽度
    const newHeight = e.clientY - resizeWrapperRect.top
    // 左侧最小宽度
    if (newHeight <= props.topHeightLimit.min) return
    if (newHeight >= props.topHeightLimit.max) return
    // 设置两侧容器的宽度
    topHeight.value = newHeight
    bottomHeight.value = resizeWrapperRect.width - topHeight.value - drapLineRect.width
  }
}
// 释放鼠标事件
const onDragEnd = (e: MouseEvent) => {
  e.preventDefault()
  isDrag.value = false
  document.removeEventListener('mousemove', onDragMove) //鼠标移动事件
  document.removeEventListener('mouseup', onDragEnd) // 鼠标释放事件
}
</script>
<style lang="less" scoped>
.resizeWrapper {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: row;
  //-webkit-app-region: no-drag;
  .drapLine {
    height: 100%;
    background-color: #e4e4e4;

    &.row:hover {
    }
    &.column:hover {
    }
    &.EwResize {
      cursor: ew-resize;
    }
    &.NResize {
      cursor: n-resize;
    }
  }
  .leftWrapper,
  .rightWrapper {
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  .auto {
    flex: 1;
  }
}
</style>
